package server.demo.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import server.demo.utils.LogUtil;

import java.util.Arrays;

/**
 * 日志记录切面
 * 自动记录方法执行日志、性能统计和异常处理
 */
@Aspect
@Component
public class LoggingAspect {
    
    private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);
    
    /**
     * 定义切点：所有Controller方法
     */
    @Pointcut("execution(* server.demo.controller.*.*(..))")
    public void controllerMethods() {}
    
    /**
     * 定义切点：所有Service方法
     */
    @Pointcut("execution(* server.demo.service.*.*(..))")
    public void serviceMethods() {}
    
    /**
     * 环绕通知：记录方法执行时间和参数
     */
    @Around("controllerMethods() || serviceMethods()")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        String operation = className + "." + methodName;
        
        // 记录方法开始执行
        logger.debug("开始执行: {} - 参数: {}", operation, Arrays.toString(joinPoint.getArgs()));
        
        try {
            // 执行原方法
            Object result = joinPoint.proceed();
            
            long duration = System.currentTimeMillis() - startTime;
            
            // 记录性能日志
            LogUtil.logPerformance(operation, duration);
            
            // 记录方法执行成功
            logger.debug("执行成功: {} - 耗时: {}ms", operation, duration);
            
            return result;
            
        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            
            // 记录异常日志
            LogUtil.logException(className, methodName, e);
            
            logger.error("执行异常: {} - 耗时: {}ms - 异常: {}", operation, duration, e.getMessage());
            
            throw e;
        }
    }
    
    /**
     * 后置通知：记录方法正常结束
     */
    @AfterReturning(pointcut = "controllerMethods()", returning = "result")
    public void logControllerReturn(JoinPoint joinPoint, Object result) {
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        
        logger.debug("Controller方法返回: {}.{} - 结果类型: {}", 
                className, methodName, 
                result != null ? result.getClass().getSimpleName() : "null");
    }
    
    /**
     * 异常通知：记录方法异常
     */
    @AfterThrowing(pointcut = "serviceMethods()", throwing = "e")
    public void logServiceException(JoinPoint joinPoint, Throwable e) {
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        
        LogUtil.logBusinessOperation(className, methodName, "FAILED: " + e.getMessage());
    }
}